import java.awt.*;
import java.awt.geom.*;

/**
* In dieser Klasse werden exemplarische ein Geradensegment, ein quadratische
* und eine kubische Kurve gezeichnet. Zur besseren Veranschaulichung werden
* Anfangs-, End- und ggf. Kontrollpunkte durch kleine Quadrate gekennzeichnet.
* Ausserdem werden bei der quadratischen und der kubischen Kurve die Tangenten
* an Anfangs- und Endpunkt eingezeichnet.
*
* @author Frank Klawonn
* Letzte Aenderung 07.01.2005
*/
public class CurveDemo extends Frame
{
  //Konstruktor
  public CurveDemo()
  {
    //Ermoeglicht das Schliessen des Fensters
    addWindowListener(new MyFinishWindow());
  }


  public void paint(Graphics g)
  {
    Graphics2D g2d = (Graphics2D) g;

    //Verwendung von Antialiasing, um die Raender weniger ausgefranst
    //erscheinen zu lassen
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

    
    //Die Linien sollen eine Dicke von 3.0 statt 1.0 haben.
    BasicStroke bs = new BasicStroke(3.0f);
    g2d.setStroke(bs);
    
    //Koordinaten fuer das Geradensegment
    int lx1 = 200;
    int ly1 = 200;
    int lx2 = 300;
    int ly2 = 300;

    //Erzeugen und Zeichnen des Geradensegments
    Line2D.Double line = new Line2D.Double(lx1,ly1,lx2,ly2);
    g2d.draw(line);

    //Markiere den Anfangspunkt in blau.
    g2d.setPaint(Color.blue);
    drawSmallSquare(lx1,ly1,g2d);

    //Markiere den Endpunkt in rot.
    g2d.setPaint(Color.red);
    drawSmallSquare(lx2,ly2,g2d);



    //Koordinaten fuer die quadratische Kurve
    int qcx1    = 300;
    int qcy1    =  50;
    int qcctrlx = 500;
    int qcctrly = 500;
    int qcx2    = 550;
    int qcy2    = 100;

    //Erzeugen und Zeichnen der quadratischen Kurve
    QuadCurve2D.Double qc = new QuadCurve2D.Double(qcx1,qcy1,qcctrlx,qcctrly,
                                                   qcx2,qcy2);
    g2d.setPaint(Color.black);
    g2d.draw(qc);

    //Markiere den Anfangspunkt in blau.
    g2d.setPaint(Color.blue);
    drawSmallSquare(qcx1,qcy1,g2d);

    //Zeichne die Verbindungsgerade vom Anfangspunkt zum Kontrollpunkt
    g2d.drawLine(qcx1,qcy1,qcctrlx,qcctrly);

    //Markiere den Kontrollpunkt in gruen.
    g2d.setPaint(Color.green);
    drawSmallSquare(qcctrlx,qcctrly,g2d);

    //Markiere den Endpunkt in rot.
    g2d.setPaint(Color.red);
    drawSmallSquare(qcx2,qcy2,g2d);

    //Zeichne die Verbindungsgerade vom Endpunkt zum Kontrollpunkt
    g2d.drawLine(qcx2,qcy2,qcctrlx,qcctrly);


    //Koordinaten fuer die kubische Kurve
    int ccx1 = 100;
    int ccy1 = 50;
    int ccctrlx1 = 150;
    int ccctrly1 = 100;
    int ccctrlx2 = 50;
    int ccctrly2 = 500;
    int ccx2 = 100;
    int ccy2 = 400;

    //Erzeugen und Zeichnen der kubischen Kurve
    CubicCurve2D.Double cc = new CubicCurve2D.Double(ccx1,ccy1,
                                                     ccctrlx1,ccctrly1,
                                                     ccctrlx2,ccctrly2,
                                                     ccx2,ccy2);
    g2d.setPaint(Color.black);
    g2d.draw(cc);

    //Markiere den Anfangspunkt in blau.
    g2d.setPaint(Color.blue);
    drawSmallSquare(ccx1,ccy1,g2d);

    //Zeichne die Verbindungsgerade vom Anfangspunkt zum ersten Kontrollpunkt
    g2d.drawLine(ccx1,ccy1,ccctrlx1,ccctrly1);

    //Markiere den ersten Kontrollpunkt in gruen.
    g2d.setPaint(Color.green);
    drawSmallSquare(ccctrlx1,ccctrly1,g2d);

    //Markiere den zweiten Kontrollpunkt in magenta.
    g2d.setPaint(Color.magenta);
    drawSmallSquare(ccctrlx2,ccctrly2,g2d);

    //Markiere den Endpunkt in rot.
    g2d.setPaint(Color.red);
    drawSmallSquare(ccx2,ccy2,g2d);

    //Zeichne die Verbindungsgerade vom Endpunkt zum zweiten Kontrollpunkt
    g2d.drawLine(ccctrlx2,ccctrly2,ccx2,ccy2);
  }


  /**
  * Zeichnet ein Quadrat mit Seitenlaenge 4 um den Mittelpunkt (x,y).
  *
  * @param x        x-Koordinate des Mittelpunktes
  * @param y        y-Koordinate des Mittelpunktes
  * @param g2d      Graphics2D-Objekt, auf das gezeichnet werden soll.
  */
  public static void drawSmallSquare(double x, double y, Graphics2D g2d)
  {
    Rectangle2D.Double rect = new Rectangle2D.Double(x-2,y-2,4,4);
    g2d.fill(rect);
  }



  public static void main(String[] argv)
  {
    CurveDemo f = new CurveDemo();
    f.setTitle("Eine kubische Kurve, ein Geradensegment und eine quadratische Kurve");
    f.setSize(600,600);
    f.setVisible(true);
  }

}

